IAM ポリシーで特定条件のアクセス制限をかけつつ、AWS サービスのアクセスは許可したいときの対処方法
困っていた内容
IAM ポリシーの条件で "aws:SourceIp"
を指定し、IP 制限をかけました。その後、CloudFormation など AWS サービスがユーザーに代わって AWS 環境を操作するサービスで、IP 制限によるエラーが出ました。
アクセス元(ソース)IP の制限は残しつつ、AWS サービスが AWS リソースへアクセスすることを許可するには、どう対応すればいいでしょうか?
どう対応すればいいの?
IAM ポリシーで "aws:SrouceIp"
を指定する "Condition"
ブロック内に、以下のポリシーを追加することで、サービス利用者のアクセスは特定の IP アドレスでアクセス制限をかけつつ、AWS サービスのアクセスは許可することができます。
{ "Bool": {"aws:ViaAWSService": "false"} }
"aws:ViaAWSService"
は AWS サービスがユーザーに代わってリクエストを実行したかどうかを判定する条件キーです。CloudFormation などの AWS サービスがアクセスした際は、値が "true"
になります。
この条件キーは以下のように使用します。
{ "Version": "2012-10-17", "Statement": { "Effect": "Deny", "Action": "*", "Resource": "*", "Condition": { "NotIpAddress": { "aws:SourceIp": [ "192.0.2.0/24", "203.0.113.0/24" ] }, "Bool": {"aws:ViaAWSService": "false"} } } }
AWS: 送信元 IP に基づいて AWS へのアクセスを拒否する - AWS Identity and Access Managementより
ポリシーの読み解き方
上記のポリシーを見てややこしいと思われる方がきっといるはず(わからなくて普通)ですので、簡単に Condition
ブロックの判定方法を補足します。
"Condition": { "NotIpAddress": { "aws:SourceIp": [ "192.0.2.0/24", "203.0.113.0/24" ] }, "Bool": {"aws:ViaAWSService": "false"} }
まず、上記の "Condition"
ブロック内は AND 判定、"aws:SourceIp"
ブロック内は OR 判定です。
CloudFormation などの AWS サービスがユーザーに代わってリクエストを実行した際は、"Bool": {"aws:ViaAWSService": "false"}
(AWS サービスのアクセスではないこと)が必ず偽と判定されるため、上述のポリシー(アクセス元 IP アドレスの制限)は無効になります。
サービス利用者(ユーザー)がリクエストを実行した際は、"Bool": {"aws:ViaAWSService": "false"}
が必ず真と判定されるため、AND 条件のアクセス元 IP アドレスの判定によって結果が決まります。
if True && <アクセス元 IP がリストに含まれるか>
のような条件式を想像してみるとわかりやすいかもしれないです。
参考資料
- AWS: 送信元 IP に基づいて AWS へのアクセスを拒否する - AWS Identity and Access Management
- 複数のキーまたは値による条件の作成 - AWS Identity and Access Management
- aws:ViaAWSService
このキーを使用して、AWS サービスがユーザーに代わって別のサービスにリクエストを実行するかどうか確認します。
サービスが IAM プリンシパルの認証情報を使用し、プリンシパルに代わってリクエストを実行すると、リクエストコンテキストキーは true を返します。サービスがサービスロールまたはサービスリンクロールを使用してプリンシパルに代わって呼び出しを行う場合、コンテキストキーは false を返します。リクエストコンテキストキーは、プリンシパルが直接呼び出しを行ったときも false を返します。